// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "tests/cefclient/browser/user_manager.h"
#include <shlobj.h>
#include <conio.h> 
#include <fstream>
#include "tests/cefclient/browser/protocol.h"
//#include "include/base/cef_logging.h"

namespace client {

namespace {

UserManager* g_user_manager = NULL;

}  // namespace

// static
UserManager* UserManager::Get() {
	if (g_user_manager == NULL) {
		g_user_manager = new UserManager();
	}
	return g_user_manager;
}


UserManager::UserManager() {
	islogin_ = false;
	_cprintf("UserManager()\n");
}

UserManager::~UserManager() {
	g_user_manager = NULL;
}

int UserManager::Construct() {
	GetDocumentsPath();
	ReadUserToken();
	return 0;
}

int UserManager::SaveLoginToken(CefString &token) {
	int ret = 0;

	HANDLE hFile;
	DWORD dwBytesToWrite = token.length() * sizeof(char);
	DWORD dwBytesWritten = 0;
	BOOL bErrorFlag = FALSE;
	std::wstring path = document_path_;
	hFile = CreateFile(path.append(L"~tmp").c_str(),                // name of the write
		GENERIC_WRITE,          // open for writing
		0,                      // do not share
		NULL,                   // default security
		CREATE_ALWAYS,             // create new file only
		FILE_ATTRIBUTE_NORMAL,  // normal file
		NULL);                  // no attr. template


	if (hFile == INVALID_HANDLE_VALUE)
	{ 
		if(LOGDEBUG) _cwprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), path.c_str());
		return -1;
	}

	bErrorFlag = WriteFile(
		hFile,           // open file handle
		token.ToString().c_str(),      // start of data to write
		dwBytesToWrite,  // number of bytes to write
		&dwBytesWritten, // number of bytes that were written
		NULL);            // no overlapped structure

	if (FALSE == bErrorFlag)
	{
		if (LOGDEBUG)  _cprintf("Terminal failure: Unable to write token %s to file.\n", token.ToString().c_str());
	}
	else
	{
		if (dwBytesWritten != dwBytesToWrite)
		{
			// This is an error because a synchronous write that results in
			// success (WriteFile returns TRUE) should write all data as
			// requested. This would not necessarily be the case for
			// asynchronous writes.
			if (LOGDEBUG)  _cprintf("Error: dwBytesWritten != dwBytesToWrite\n");
		}
		else
		{
			if (LOGDEBUG)  _cwprintf( L"Wrote %d bytes to %s successfully.\n", dwBytesWritten, path.c_str());
		}
	}

	CloseHandle(hFile);
	token_ = token.ToString();
	islogin_ = true;
	return ret;
}

std::string UserManager::GetLoginToken( ) {
	return token_;
}


bool UserManager::IsLogin() {
	return islogin_;
}

void  UserManager::DownLoadUserIcon(const std::string &url) {

	if (LOGDEBUG)  _cprintf("start DownLoadUserIcon  %s\n", url.c_str());
	CefRefPtr<CefRequest> request = CefRequest::Create();
 
	CefString curl;
	curl.FromString(url);
	request->SetURL(curl);
	request->SetMethod("GET");
	CefRefPtr<CefURLRequest> url_request = CefURLRequest::Create(request, new UrlRequestClient(new UserIconRequestHandler()), NULL);

}

std::string  UserManager::ReadUserInfo() {
	std::wstring s = GetUserDataPath();
	s.append(L"u");

	std::ifstream t(s.c_str());
	if (!t.good()) {
		if (LOGDEBUG) _cprintf("Can not open  user file %s\n", s.c_str());
		return "";
	}
	std::string str((std::istreambuf_iterator<char>(t)),
		std::istreambuf_iterator<char>());
	t.close();
	return str;
}

void UserManager::Logout() {
	islogin_ = false;
	token_.clear();
}

std::wstring  UserManager::GetUserDataPath() {
	std::wstring s = document_path_;
	s.append(L"Data\\");
	return s;
}

CefString UserManager::GetCachePath() {
	std::wstring s = document_path_;
	s.append(L"Cache\\");
	return s;
}

CefString UserManager::GetPlayCachePath() {
	std::wstring s = document_path_;
	s.append(L"WebCache\\");
	return s;
}

std::wstring UserManager::GetJsPath() {
	std::wstring s = document_path_;
	s.append(L"AfterSome");
	return s;
}
 
void UserManager::GetDocumentsPath() {
//	 document_path_ 
	TCHAR my_documents[MAX_PATH];
	HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, my_documents);

	document_path_.append(my_documents).append(L"\\UPUPOO\\");

	if (LOGDEBUG)  _cwprintf(L"document path is  %s   result = %d\n", document_path_.c_str(), result);

}

void UserManager::ReadUserToken() {
	std::wstring path = GetUserDataPath();
	path.append(L"~tmp"); 
	std::ifstream t(path.c_str());
	if (!t.good()) {
		if (LOGDEBUG)  _cprintf("Can not open  file to read token %s\n", path.c_str());
		islogin_ = false;
		return;
	}
	std::string str((std::istreambuf_iterator<char>(t)),
		std::istreambuf_iterator<char>());
	t.close();
	token_ = str;
	if (!token_.empty()) {
		islogin_ = true;
	}
	else {
		islogin_ = false;
	}
	if (LOGDEBUG) _cprintf("read token %s\n", token_);
}

//HWND UserManager::GetRootHandler() {
//	return root_handler_;
//}

UserIconRequestHandler::UserIconRequestHandler( ) {
	if (LOGDEBUG)  _cprintf("UserIconRequestHandler()\n");
}

void UserIconRequestHandler::OnCompletion(CefURLRequest::ErrorCode errorCode, const  std::string & data) {
	std::wstring path = UserManager::Get()->GetUserDataPath();
	path.append(L"usericon.jpg");
	std::ofstream savefile(path, std::ios_base::binary);
	savefile.write(data.c_str(), data.length() + 1);
	if (LOGDEBUG)  _cprintf("UserIconRequestHandler::OnCompletion\n");
}

void UserIconRequestHandler::OnRequestFailed() {
	if (LOGDEBUG)  _cprintf("UserIconRequestHandler::OnRequestFailed\n");
}



}  // namespace client
